Log In  
[back to top]


As simple as the subject.

  • Write a cart that uses btnp().
  • Run the cart.
  • Press and hold a button to see it repeats.
  • Hit esc to stop the cart.
  • Enter 'resume' to resume the cart.
  • Press and hold a button and see if it fails.

(Either that or key repeat isn't supposed to be a thing with btnp() and it only works right after you resume.)

This code is sufficient to show it:

boops=0
function _update()
  if btnp()!=0 then
    boops+=1
    print("boop #"..boops)
  end
end

Note: tested on win64 version.

1 comment



The manual implies that the line-continuation syntax might allow for this...

line( 10,10, 20,10, 1 )
line(        20,20, 2 )
line(        10,20, 3 )
line(        10,10, 4 )

...which would make a rectangle with four differently-colored sides.

But PICO-8 seems to interpret line(x2,y2,col) as line(x1,y1,x2,0).

1
3 comments



attn: @zep

I can't remember if this was fixed the last time we reported it, but if it was, it's broken again.

Using backticks to insert inline code in text is broken, causing the entire remainder of the paragraph to be highlighted as code, even if the closing backtick is present.

For instance, this is how I'll write the next paragraph:

If this is already fixed, `this highlight should stop` <-- HERE.

If this is already fixed, this highlight should stop <-- HERE.

Also, just want to mention that I wish the inline code were simply a mono-spaced font, and not inverse the way it is now. It's visually jarring the way it is. :/

2
2 comments



attn: @zep

A tab character is supposed to move the cursor to the next column that's a multiple of the tab-width setting, but instead it just advances the cursor by tab-width columns every time.

In other words, it currently does this:

function do_tab()
  cursor_x += tab_width
end

And it should do this:

function do_tab()
  cursor_x = (cursor_x + tab_width - 1) % tab_width
end
3
1 comment



@zep

I'm trying to write a tool that has text editing, and I find that the devkit keyboard doesn't return a lot of the special keys that it easily could.

You're returning a string, so there's no reason why it has to be just one character. So pressing the Home key could simply return the string "home". No need for special characters, escape sequences, etc., since these verbose names would all be distinct from any single regular typed character.

I'm mainly thinking of the standard navigation cluster: up, down, left, right, ins, del, home, end, pgup, pgdn.

It'd also be nice if there were a second stat() value that had a bitmask of the modifier keys that are currently pressed, if the host has them. Like, left/right shift, left/right alt/cmd, maybe left/right win/opt, altgr, maybe capslock. Not crucial, but definitely helpful. It'd be nice to be able to support things like ^Z for undo in my tool.

I say all this because one of the things I love about PICO-8 is working entirely within PICO-8, so it's nice to write tools that work inside of the platform, but the devkit functionality is a little limited in this department.

[ Continue Reading.. ]

5
1 comment



@zep

If I type this:

Look at my `inline code` please.

I get this, which I'm just going to let the BBS handle, so it might look right to anyone reading this after it's fixed:

Look at my inline code please.

The second backtick isn't closing the inline code.

As an aside, I personally would prefer it if inline code were simply a monospaced font, and not inverted as it is now. It makes using inline code very ugly and hard on the eyes. :/

I do like the old-printer-paper code block format though. :)

1
2 comments



@zep

I notice Benjamin Soulé's username doesn't show up right, even after your emoji fix.

See here:

https://lexaloffle.com/bbs/?tid=3421

Looks like this at my end:

It seems to work fine inside this post's text though.

Edit: Yeah, there's some kind of encoding issue, not a font issue, because if I copy and paste it here, it still comes out "Benjamin Soul�", even though I was able to write it correctly above.

3
1 comment



Re: https://twitter.com/johanpeitz/status/1024750757944410112

Cart #54585 | 2018-08-02 | Code ▽ | Embed ▽ | No License

0 comments



I've seen a lot of threads where people talk about using mini JSON (JavaScript Object Notation) parsers, but there are always caveats about the differences betwen JS and Lua.

I've prototyped a little parser for what I call LTN (Lua Table Notation, pronounced "loot'n"), which effectively gives you the ability to specify a Lua table's contents, in Lua source format, inside a string. For instance, if you had this:

player=
{
	name="lone wanderer",
	desc="alone.\nwandering.\n",
	x=123,
	y=456,
	attrs=
	{
		str=5,per=3,edr=5,chr=3,int=4,agi=3,lck=4,
		hp=100,mp=20
	}
}

You could swap out the outer curlies for Lua's multi-line string braces ("[[ ... ]]") and add a call to my parser, omitting the parens since it's a single string param and Lua lets you do that:

player=ltn
[[
	name="lone wanderer",
	desc="alone.\nwandering.\n",
	x=123,
	y=456,
	attrs=
	{
		str=5,per=3,edr=5,chr=3,int=4,agi=3,lck=4,
		hp=100,mp=20
	}
]]

[ Continue Reading.. ]

5
7 comments



In the expandable textarea you get when you click Code under a cart, tabs are defaulting to 8 spaces, which is really ugly and rapidly pushes off of the right.

I found info here on how to fix it. If we assume that you're setting tabs to a default of 2 spaces in 0.1.12, then you'd want to do this for the code textarea:

style: -moz-tab-size: 2; -o-tab-size: 2; tab-size: 2;

Because intarwebz haz standardz. I mean, look at that crap. Not just three versions, but two start with hyphens. WTF.

You should also do this for the div surrounding [code]...[/code] regions of posts.

PS: Remember also to fix the broken glyph translation in the textarea.

3 comments



I've noticed that with palt() you can leave off the boolean argument and it will default to true, letting you say "palt(11)" if you want index 11 to be transparent. Edit: Uh, turns out I was wrong about this, but the rest of this is still a good suggestion, and as I say below, it'd actually be nice if palt(x) did work this way as well.

There's no equivalent for pal() though. If you leave off the second argument, it acts like you didn't give any arguments and resets the entire palette.

Suggestion: It'd be nice if pal(x) simply acted like pal(x,x), a quick way to reset a single entry to default.

1
2 comments



(Hoping to catch you before you finalize 0.1.12)

Similar to how I felt ceil() was missing from the fundamental math toolset in PICO-8, I feel like there are a couple of fundamentals missing from the table toolset.

Would it be reasonable to add these to the built-in table operators?

function ins(table, index, elem)
  local temp = elem
  while temp ~= nil do
    table[index],temp = temp,table[index]
    index = index + 1
  end
  return elem
end

function pop(table)
  local elem = table[#table]
  table[#table] = nil
  return elem
end

-- (and possibly this alias, just for the sake of being symmetrical with pop)
push = add

[ Continue Reading.. ]

4
0 comments



I discovered tonight that the modulo (%) operator is treating the nadir value, 0x8000, as if it is positive, whereas other math ops treat it as negative:

> ?0x7ffe/10
3276.6
> ?0x7fff/10
3276.7
> ?0x8000/10
-3276.8            <-- as expected, -32768/10 == -3276.8
> ?0x8001/10
-3276.7
> ?0x8002/10
-3276.6

> ?0x7ffe%10
6
> ?0x7fff%10
7
> ?0x8000%10
8                  <-- unexpected, -32768%10 should be 2
> ?0x8001%10
3
> ?0x8002%10
4

I'm guessing this is an edge-case side effect of whatever you do to make modulo not flip directions at 0 (which I'm very glad you do).

0 comments



Cabledragon was talking to me about perlin and simplex noise generation, and we were looking at various web pages on the subject. One of them was a novel implementation of a simplex noise generator, written by Kurt Spencer, a game dev who did not wish to be subject to Perlin's patent on his own version of simplex noise:

http://uniblock.tumblr.com/post/97868843242/noise

With a public-domain javascript implementation of 2D, 3D, and 4D noise here:

https://gist.github.com/kdotjpg/b1270127455a94ac5d19

The 3D and especially the 4D code is rather long and spaghettilike, though I suspect for good reason, but I noticed the 2D code was not too bad, really, so I took a pair of Lua shears to it and made it fit on our little platform.

It performs pretty well. It looks good, and while you can't efficiently use it to set every pixel on your screen, it's quite adequate for caching your terrain at app launch, or even for real-time generation of the area immediately around you, if you can be somewhat economical with how many times you sample the noise.

Note that, as mentioned in the code, the shell I wrote around this adaptation isn't particularly useful. It's just a custom-made and optimized-to-the-point-of-being-ugly viewer for the noise generator.

[b]The generator code is on the second tab, and that's what you'll want to look at if you want to use it yourself.

[color=#ffaabb] [ Continue Reading.. ]

27
13 comments



So you've told us we can suppress the system pause menu with this:

poke(0x5f30,1)

And that works great. However, I wanted to write something that allows you to access both the game pause and the system pause, by using short presses for game pause and long presses for system pause. Unfortunately, there's a bug/misfeature/oversight that prevents this:

You're still debouncing the button at the system level, even if the system menu is disabled, so if the button is held down, it's only reported down on the first frame. This prevents me from detecting a long press.

I'm guessing this is just because you check the menu-suppression flag after you've recognized and absorbed the button press, rather than wrapping the button check as well.

Any chance of a fix in the next version? :)

4 comments



I seem to recall that you said you might break some elements of backwards-compatibility in 0.2. If so, I have a request. I'm not sure it'd even break anything, to be honest.

Current PICO-8 executables allow the use of // instead of -- for comments. This has the unfortunate side effect of preventing us from using lua's // operator, which is the 'idiv' operator, e.g. a//b == flr(a/b).

I have never seen anyone upload code that uses "//" comments, so I think it might not even break anything. You'd probably know better, since you presumably have all of the uploaded carts in some kind of database. If nothing else, maybe you could disable it based on the version number you added to files recently?

It'd just be nice sometimes to use that operator, and if it's already supported but masked by the alternate comment form, I'd hope it wouldn't be a big chore to unmask it.

Thanks...

2
9 comments



Converting shr() safely to simple math:

shr(v, 16) ==> v * 0x.0001
shr(v, 15) ==> v * 0x.0002
...
shr(v,  2) ==> v * 0x.4000 (or 0.25)
shr(v,  1) ==> v * 0x.8000 (or 0.5)

Multiplying by the fraction avoids a hazard where a negative number can go to 0 when dividing by numbers greater than 1, which destroys the sign-extending upper bits you expect to keep with shr().

It also allows shifts up to 16, whereas dividing only allows shifts up to 14. This is because PICO-8 can't represent any powers of 2 larger then 16384.

Similarly, because it is safe to divide by a fractional number less than 1, you can use the same idea to shift left up to 16 bits:

shl(v, 16) ==> v / 0x.0001
shl(v, 15) ==> v / 0x.0002
...
shl(v,  2) ==> v / 0x.4000 (or 0.25)
shl(v,  1) ==> v / 0x.8000 (or 0.5)

In this case, it's down to style or the need to shift by more than 14. Unlike dividing, multiplying by values greater than 1 is safe, so you can also obviously just convert shl(v,2) to v*4. PICO-8 performs divides as fast as multiplies, so performance is the same either way.

Basically, your safe bet is always to use the fractional power of two, whether dividing or multiplying. If you want to be sure, start your constant with "0x." and you'll always get it the right way around. :)

The reason some of us want to do this, rather than the more-intuitive shift calls, is that it saves one token per shift. That can add up quickly in a program heavy with binary math.

3
1 comment



On yonder thread, where you wisely noted we should stop polluting its subject, you responded to me and said:

[box=404040]Static preprocessors like cpp are a weird fit for dynamic languages like Lua. For example, cpp-style includes have no order-dependent side effects in the languages they're used for (other than in the preprocessor macro language itself, I think?), so they can more simply insert code at first mention. This is not the case in Lua. Lua modules make the handling of side effects in the code explicit, so there's no confusion as to what a require() is expected to do. I'm very interested to know why a Pico-8 developer would prefer an #include-like to a require() because I can't think of a reason, as long as require() is implemented correctly.

Re: defines and such, I think what we actually want, especially in the context of Pico-8, is build-time constant folding and dead code elimination.

But we should take build tool discussion somewhere else, so people can use this thread to discuss Compos. :)

[color=#ffaabb] [ Continue Reading.. ]

16 comments



EDIT: Fixed as of 0.2.0!

Original post:


Pretty sure when you originally added _update60(), you compensated for the doubled frame rate when returning time() values, but these days time() is running at double speed when you have _update60() instead of _update().

I noticed this when playing with a simple seven-segment-display demo. Here's one that uses update() and updates once per second as expected:

Cart #49956 | 2018-03-05 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

And this is the same cart, but switched to _update60() and runs twice as fast:

Cart #49957 | 2018-03-05 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

1 comment



Adapting a solution found ca. pages 179-180 of this white paper:

support.amd.com/TechDocs/25112.PDF (archived)

Apparently it's commonly called "popcount" or "popcnt", after an asm instruction on some CPUs. Basically, it's the population-of-1's count. I think I assumed it would be called "bitcount".

I finagled it into this PICO-8-specific form, which counts every bit (including fractional bits) in constant and pretty-brief time, with just 2 muls, 2 adds, 3 shifts, and 5 bitwise ops:

function popcount(v)
    v-=v>>>1&0x5555.5555
    v=(v&0x3333.3333)+(v>>>2&0x3333.3333)
    return (v*0x1.1&0x0f0f.0f0f)*0x0101.0101<<8&0xff
end

It's a bit uglier than it would be in C/C++, but it's mostly the same operations, with a minor adaptation for the 16-bit shifts inherent in 16.16 fixed-point multiplies. PICO-8 also benefits from being able to do a fast multiply by a fixed-point value like 0x1.1 in the third line of the function, which would have required a shift and an add otherwise.

[ Continue Reading.. ]

6
3 comments





Top    Load More Posts ->